package com.funong.matrix.biz.power.domain;

import cn.hutool.core.lang.tree.Tree;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.funong.matrix.biz.base.dao.SysMenuDao;
import com.funong.matrix.biz.base.dao.SysRoleMenuDao;
import com.funong.matrix.biz.base.entity.SysMenuEntity;
import com.funong.matrix.biz.base.entity.SysRoleMenuEntity;
import com.funong.matrix.biz.power.pojo.dto.SysRolePermissionDTO;
import com.funong.matrix.core.dto.QueryDTO;
import com.funong.matrix.core.dto.Result;
import com.funong.matrix.core.enums.IsDeletedEnum;
import com.funong.matrix.core.utils.DateTimeUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * @author : NaNa
 * @since : 2023-05-19 16:44
 **/
@Slf4j
@Service
public class SysMenuDomainDao {
    @Resource
    private SysMenuDao menuDao;
    @Resource
    private SysRoleMenuDao roleMenuDao;

    public Result queryByCondition(QueryDTO<SysMenuEntity> queryDTO) {
        IPage<SysMenuEntity> menuEntityIPage = menuDao.queryByCondition(queryDTO);
        return Result.page(menuEntityIPage);
    }

    /**
     * baocun1
     *
     * @param menuEntity
     * @return
     */
    public Boolean saveOrUpdateMenu(SysMenuEntity menuEntity) {
        Integer menuId = menuEntity.getId();
        boolean result;
        if (null == menuId) {
            result = menuDao.save(menuEntity);
        } else {
            result = menuDao.updateById(menuEntity);
        }
        return result;
    }

    public SysMenuEntity getMenuById(Integer menuId) {
        return menuDao.getById(menuId);
    }

    public SysMenuEntity getMenuByCode(String code) {
        return menuDao.getMenuByCode(code);
    }

    public List<String> queryMenuCodeByRoleCode(List<String> roleCodeList) {
        List<SysRoleMenuEntity> roleMenuEntityList = roleMenuDao.getMenuListByRoleCodeList(roleCodeList);
        return roleMenuEntityList.stream().map(SysRoleMenuEntity::getMenuCode).distinct().collect(Collectors.toList());
    }

    public List<SysMenuEntity> getMenuListByRoleCodeList(List<String> roleCodeList) {
        List<SysRoleMenuEntity> roleMenuEntityList = roleMenuDao.getMenuListByRoleCodeList(roleCodeList);
        List<String> menuCodeList = roleMenuEntityList.stream().map(SysRoleMenuEntity::getMenuCode).distinct().collect(Collectors.toList());
        if (CollectionUtils.isEmpty(menuCodeList)) {
            return new ArrayList<>();
        }
        List<SysMenuEntity> menuDetailList = menuDao.getMenuListByCodeList(menuCodeList);
        if (CollectionUtils.isEmpty(menuDetailList)) {
            return new ArrayList<>();
        }
        return treeMenuList(menuDetailList);
    }

    public Boolean updateMenuStatus(Integer menuId, Integer status) {
        SysMenuEntity menuEntity = menuDao.getById(menuId);
        if (null == menuEntity) {
            return false;
        }
        menuEntity.setStatus(status).setUpdatedAt(DateTimeUtil.now());
        boolean uptResult = menuDao.updateById(menuEntity);
        return uptResult;
    }

    /**
     * 删除菜单
     *
     * @param menuId
     * @return
     */
    public Boolean deleteMenu(Integer menuId) {
        SysMenuEntity menuEntity = menuDao.getById(menuId);
        if (null == menuEntity) {
            return false;
        }
        menuEntity.setIsDeleted(IsDeletedEnum.DELETED.getValue());
        boolean uptResult = menuDao.updateById(menuEntity);
        return uptResult;
    }

    public void saveRoleMenu(SysRolePermissionDTO rolePermissionDTO) {
        roleMenuDao.deleteRoleMenu(rolePermissionDTO.getRoleCode());
        if (CollectionUtils.isNotEmpty(rolePermissionDTO.getMenuCodeList())) {
            for (String menuCode : rolePermissionDTO.getMenuCodeList()) {
                SysRoleMenuEntity roleMenuEntity = new SysRoleMenuEntity().setRoleCode(rolePermissionDTO.getRoleCode())
                        .setMenuCode(menuCode);
                roleMenuEntity.setCreatedAt(DateTimeUtil.now());
                roleMenuEntity.setUpdatedAt(DateTimeUtil.now());
                roleMenuDao.save(roleMenuEntity);
            }
        }
    }

    public List<SysMenuEntity> getMenuTree(Integer systemId) {
        List<SysMenuEntity> menuDetailList = menuDao.getMenuListBySystem(systemId);
        if (CollectionUtils.isEmpty(menuDetailList)) {
            return menuDetailList;
        }
        return treeMenuList(menuDetailList);
    }

    private List<SysMenuEntity> treeMenuList(List<SysMenuEntity> menuDetailList) {
        List<SysMenuEntity> parentMenuList = menuDetailList.stream()
                .filter(i -> i.getLevel() == 1)
                .sorted(Comparator.comparing(SysMenuEntity::getOrderNum))
                .collect(Collectors.toList());
        Map<String, List<SysMenuEntity>> menuMap = menuDetailList.stream()
                .sorted(Comparator.comparing(SysMenuEntity::getOrderNum))
                .collect(Collectors.groupingBy(SysMenuEntity::getParentCode));
        parentMenuList.forEach(firstMenu -> {
            List<SysMenuEntity> secondMenuList = menuMap.get(firstMenu.getCode());
            if (!CollectionUtils.isEmpty(secondMenuList)) {
                secondMenuList.forEach(secondMenu -> {
                    List<SysMenuEntity> thirdChildren = menuMap.get(secondMenu.getCode());
                    if (!CollectionUtils.isEmpty(thirdChildren)) {
                        secondMenu.setChildren(thirdChildren);
                    }
                });
                firstMenu.setChildren(secondMenuList);
            }
        });
        return parentMenuList;
    }

    /**
     * 下拉选择
     *
     * @param systemId
     * @return
     */
    public List<Tree<String>> querySelect(Integer systemId) {
        return menuDao.querySelect(systemId);
    }
}
